// #include "../subject/server.hpp"
// #include <functional>

// void HandleClose(Channel *chn)
// {
//     DBG_LOG("close fd:%d", chn->Fd());
//     chn->Remove();
//     delete chn;
// }
// void HandleRead(Channel *chn)
// {
//     /*拿到fd， 然后向fd中读取数据*/
//     char buffer[1024];
//     int fd = chn->Fd();
//     int ret = recv(fd, buffer, sizeof(buffer), 0);
//     if (ret > 0)
//     {
//         buffer[ret] = 0;
//     }
//     else if (ret == 0)
//     {
//         DBG_LOG("没有数据， 读取到0个数据");
//     }
//     else if(ret < 0)
//     {
//         ERR_LOG("读取失败, 关闭当前事件监控, Fd: %d", chn->Fd());
//         HandleClose(chn);
//         return;
//     }
//     DBG_LOG("%s", buffer);
//     chn->EnableWrite();

// }
// void HandleWrite(Channel *chn)
// {
//     /*拿到fd， 直接向fd中写入数据*/
//     std::string str = "hi, world!";
//     int fd = chn->Fd();
//     int ret = send(fd, str.c_str(), str.size(), 0);
//     if (ret < 0)
//     {
//         if (errno == EAGAIN || errno == EINTR)
//         {
//             INF_LOG("非阻塞读取或者信号中断");
//             return;
//         }
//         ERR_LOG("写入失败，关闭事件");
//         HandleClose(chn);
//         return;
//     }
//     /*写完了， 就关闭写事件*/
//     chn->DisableWrite();

// }
// void HandleError(Channel *chn)
// {
//     /*出错了， 就直接关闭事件就行了*/
//     HandleClose(chn);
// }

// void HandleEvent(EventLoop* loop, int timerfd, Channel *chn)
// {
//     /*任意事件*/
//     loop->TimerRefresh(timerfd);
//     return;
// }

// void Acceptor(EventLoop *loop, Channel *chn)
// {
//     /*建立新连接就是拿到新的fd， 然后根据新的fd和已经传进来的poller创建好新的Channel。然后添加到epoll模型中*/
//     int fd = chn->Fd();
//     int newfd = accept(fd, nullptr, nullptr);
//     if (newfd < 0)
//     {
//         ERR_LOG("Acceptor, 获取新连接失败");
//         return;
//     }
//     int timerfd = (rand() ^ (rand() % 10000));

//     Channel *newch = new Channel(loop, newfd);            /*注意， 这里不能直接创建栈区变量， 要创建静态变量。 否则就直接销毁了， 添加到poller的哈希表中
//              也没有用了*/
//     newch->SetReadCallback(std::bind(HandleRead, newch));   /*可读事件回调函数*/
//     newch->SetWriteCallback(std::bind(HandleWrite, newch)); /*可写事件回调函数*/
//     newch->SetCloseCallback(std::bind(HandleClose, newch)); /*关闭事件回调函数*/
//     newch->SetErrorCallback(std::bind(HandleError, newch)); /*错误事件回调函数*/
//     newch->SetEventCallback(std::bind(HandleEvent, loop, timerfd, newch)); /*任意事件回调函数*/

//     /*添加定时器任务， 必须在启动读事件之前，因为有可能刚刚启动读事件， 就触发了， 但是此时还没有定时器任务， 调用
//     任意时间的时候调用不了， 因为没有读事件，结果就abort了*/
//     loop->AddTimer(timerfd, 10, std::bind(HandleClose, newch));
//     newch->EnableRead();

// }

#include "../subject/server.hpp"
#include <functional>

EventLoop base_loop;
int conn_id = 0;
std::unordered_map<uint64_t, PtrConn> _conns;
LoopThreadPool *loop_pool;   

void MessageCallBack(const PtrConn &pcn, Buffer *buf)
{
    DBG_LOG("%s", buf->ReadPosition());
    buf->MoveReadOffset(buf->ReadAbleSize());

    std::string str = "hello world";
    pcn->Send((char *)str.c_str(), str.size());
}

void ServerCloseCallBack(const PtrConn &pcn)
{
    _conns.erase(pcn->Id());
}

void ConnectedCallBack(const PtrConn &pcn)
{
    DBG_LOG("crreate a new Connected %p", pcn.get());
}

void newConnection(int fd)
{
    /*建立新连接就是拿到新的fd， 然后根据新的fd和已经传进来的poller创建好新的Channel。然后添加到epoll模型中*/
    conn_id++;
    PtrConn newconn(new Connection(loop_pool->Next_loop(), conn_id, fd)); //*第一个连接， 第一个连接的任意时间一直被触发。
    newconn->SetMessageCallback(std::bind(MessageCallBack, std::placeholders::_1, std::placeholders::_2));
    newconn->SetServerClosedCallback(std::bind(ServerCloseCallBack, std::placeholders::_1));
    newconn->SetConnectedCallback(std::bind(ConnectedCallBack, std::placeholders::_1));
    newconn->EnableInactiveRelease(5);
    newconn->Established(); /*通过Connection里面的Establish函数调用loop的Inloop函数，在里面跟新Epoll模型*/
    _conns.insert({conn_id, newconn});
}

int main()
{
    loop_pool = new LoopThreadPool(&base_loop);
    loop_pool->SetThreadCount(2);
    loop_pool->Create();
    Acceptor apt(&base_loop, 8080);
    apt.SetAcceptCallback(std::bind(&newConnection, std::placeholders::_1));
    apt.Listen();

    base_loop.Start();
    return 0;
}
